home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
pdsrt212.zip
/
MERGE.C
< prev
next >
Wrap
Text File
|
1990-06-05
|
4KB
|
152 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <alloc.h>
#include <limits.h>
#include "queue.h"
typedef struct RunStruct {
unsigned long Begin;
unsigned long Count;
} RUN_ENT;
static struct RunArray {
unsigned long Current;
unsigned long Count;
int Index;
char **Buf;
} *RA;
static unsigned long BufSize;
static unsigned BufCount;
static char **OutBuf;
static int O_Index;
static int Low;
void FillRunBuffer (int x);
void WriteOutputBuffer (void);
void
Merge (void) {
extern FILE *fint, *fout;
extern QUE_DEF Runs;
extern int RecLen;
extern int comp(const void *a, const void *b);
extern char **SortArray;
extern int S_ArraySize;
extern char IntName[65];
int i, j;
QUE_ENTRY *t;
RUN_ENT *p;
unsigned long MemLeft;
for (i = 0; i < S_ArraySize; ++i) free(SortArray[i]);
free(SortArray);
MemLeft = (S_ArraySize * sizeof(char far *)) + (S_ArraySize * (RecLen + 2));
if ((fint = freopen(IntName, "r", fint)) == NULL) {
fprintf(stderr, "%s\n", IntName);
fprintf(stderr, "Major error! %d", errno);
perror("");
exit(1);
}
if ( (RA = malloc(Runs.Count * sizeof(struct RunArray) ) ) == NULL) {
fprintf(stderr, "Major Error. Insufficient memory for run array.\n");
exit(1);
}
MemLeft -= (Runs.Count * sizeof(struct RunArray));
BufSize = MemLeft / (Runs.Count + 1);
if (BufSize > UINT_MAX) BufSize = UINT_MAX;
BufCount = (int) (BufSize / (RecLen + 2 + sizeof(char *)));
BufSize = BufCount * (RecLen + 2);
for (i = 0, t = Runs.Head; t != NULL; ++i, t = t->Next) {
p = t->Body;
RA[i].Current = p->Begin;
RA[i].Count = p->Count;
RA[i].Index = 0;
if ((RA[i].Buf = malloc(BufCount * sizeof(char *))) == NULL) {
fprintf(stderr, "Major Error. Insufficient memory for run item\n");
exit(1);
}
MemLeft -= BufCount * sizeof(char *);
for (j = 0; j < BufCount; ++j) {
if ((RA[i].Buf[j] = malloc(RecLen + 2)) == NULL) {
fprintf(stderr, "Major Error. Insufficient memory for run item buffer.\n");
exit(1);
}
MemLeft -= RecLen + 2;
}
}
if ((OutBuf = malloc(BufCount * sizeof(char *))) == NULL) {
fprintf(stderr, "Insufficient memory: 3\n");
exit(1);
}
MemLeft -= BufCount * sizeof(char *);
for (j = 0; j < BufCount; ++j) {
if ((OutBuf[j] = malloc(RecLen + 2)) == NULL) {
fprintf(stderr, "Insufficient memory: 4\n");
exit(1);
}
MemLeft -= RecLen + 2;
}
O_Index = 0;
for (i = 0; i < Runs.Count; ++i) FillRunBuffer(i);
Low = 0;
while (1) {
for (Low = 0, i = 1; i < Runs.Count; ++i) {
if (comp(&RA[i].Buf[RA[i].Index], &RA[Low].Buf[RA[Low].Index]) < 0)
Low = i;
}
if (RA[Low].Buf[RA[Low].Index] == NULL) break;
strcpy(OutBuf[O_Index++], RA[Low].Buf[RA[Low].Index++]);
if (RA[Low].Index >= BufCount) FillRunBuffer(Low);
if (O_Index >= BufCount) WriteOutputBuffer();
}
if (O_Index > 0) WriteOutputBuffer();
fclose(fint);
fclose(fout);
}
void
FillRunBuffer (int x) {
int i;
fseek(fint, RA[x].Current, SEEK_SET);
for (i = 0; (i < BufCount) && (i < RA[x].Count); ++i)
fgets(RA[x].Buf[i], RecLen, fint);
RA[x].Count -= i;
for (; i < BufCount; ++i) RA[x].Buf[i] = NULL;
RA[x].Current = ftell(fint);
RA[x].Index = 0;
}
void
WriteOutputBuffer (void) {
extern int errno;
extern long OutCount;
int i;
for (i = 0; i < O_Index; ++i) {
fputs(OutBuf[i], fout);
if (errno) {
perror("I/O error on output file");
exit(1);
}
OutCount++;
}
O_Index = 0;
}